
#include "TwoWayList.cc"
#include "Record.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <iostream.h>


void Page :: EmptyItOut () {

	// get rid of all of the records
	while (1) {
		Record temp;
		if (!GetFirst (temp))
			break;
	}	

	// reset the page size
	curSizeInBytes = sizeof (int);
	numRecs = 0;
}

int Page :: GetFirst (Record &firstOne) {


	// move to the first record
	myRecs.MoveToStart ();

	// make sure there is data 
	if (!myRecs.RightLength ()) {
		return 0;
	}

	// and remove it
	myRecs.Remove (firstOne);
	numRecs--;
	curSizeInBytes -= firstOne.GetLength ();
	return 1;

}

int Page :: Append (Record &addMe) {

	// first see if we can fit the record
	if (curSizeInBytes + addMe.GetLength () > PAGESIZE) {
		return 0;
	}

	// move to the last record
	myRecs.MoveToFinish ();

	// and add it
	curSizeInBytes += addMe.GetLength ();
	myRecs.Insert (addMe);
	numRecs++;
	return 1;
	
}

Page :: Page () {
	curSizeInBytes = sizeof (int);
	numRecs = 0;
}

Page :: ~Page () {
	EmptyItOut ();
}

void Page :: ToBinary (char *bits) {

	// first write the number of records on the page
	((int *) bits)[0] = numRecs;

	char *curPos = bits + sizeof (int);

	// and copy the records one-by-one
	myRecs.MoveToStart ();

	for (int i = 0; i < numRecs; i++) {
		
		//cout << "Making a record binary!!\n";

		// copy over the bits of the current record
		curPos += myRecs.Current (0).ToBinary (curPos);

		// and traverse the list
		myRecs.Advance ();
	}
        curPos = 0;
}

void Page :: FromBinary (char *bits) {

	// first read the number of records on the page
	numRecs = ((int *) bits)[0];

	// sanity check
	if (numRecs > 1000000 || numRecs < 0) {
		cerr << "This is probably an error.  Found " << numRecs << 
			" records on a page.\n";
		exit (1);
	}
	
	//cout << "Found " << numRecs << " recs.\n";

	// and now get the binary representations of each
	char *curPos = bits + sizeof (int);

	// first, empty out the list of current records
	myRecs.MoveToStart ();
	while (myRecs.RightLength ()) {
		Record temp;
		myRecs.Remove (temp);
	}

	// now loop through and re-populate it
	curSizeInBytes = sizeof (int);
	for (int i = 0; i < numRecs; i++) {

		// create the record
		Record temp;
		curPos += temp.FromBinary (curPos);
		curSizeInBytes += temp.GetLength ();

		// and add it
		myRecs.Insert (temp);

                // advance twoWayList to preserve the order of the disk page
                myRecs.Advance();
	}
	myRecs.MoveToStart ();
}

